package cn.airfei.aircore.core.common;


import cn.airfei.aircore.core.enums.RespEnum;
import cn.airfei.aircore.core.exception.AppException;
import cn.airfei.aircore.core.extend.InsertLogToMongoDb;
import cn.airfei.aircore.core.extend.ParseHeaderAuthorization;
import cn.airfei.aircore.core.properties.AirCoreProperty;
import cn.airfei.aircore.core.storage.Pojo.LogForMongoDbPojo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;

/**
 * 统一抛出异常
 *
 * @author air
 * @create 2019年05月30日15:59:31
 */
@RestControllerAdvice
@Slf4j
@Component
@ApiIgnore
public class Error implements ErrorController {
    @Resource
    private AirCoreProperty airCoreProperty;

    @Resource
    private InsertLogToMongoDb insertLogToMongoDb;

    @Resource
    private ParseHeaderAuthorization parseHeaderAuthorization;

    /**
     * 拦截控制器请求错误信息
     *
     * @param req req
     * @param e   exception
     * @return resp
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    public Resp defaultErrorHandler(HttpServletRequest req, Exception e, HttpServletResponse response) throws Exception {
        // 写入日志到mongoDb
        if (airCoreProperty.getSetLogToMongoDb()) {
            String url = String.valueOf(req.getRequestURL());
            if (!StringUtils.isEmpty(req.getQueryString())) {
                url = url + "?" + req.getQueryString();
            }
            LogForMongoDbPojo logForMongoDbPojo = new LogForMongoDbPojo();
            logForMongoDbPojo.setErrMsg(e.getMessage());
            logForMongoDbPojo.setCreateTime(LocalDateTime.now());
            logForMongoDbPojo.setUrl(url);
            logForMongoDbPojo.setTraceId(String.valueOf(req.getAttribute("traceId")));
            logForMongoDbPojo.setIp(req.getRemoteAddr());
            logForMongoDbPojo.setMethod(req.getMethod());
            logForMongoDbPojo.setErrCode(RespEnum.SYSTEM_ERROR.getCode());
            parseHeaderAuthorization.setLoginInfo(logForMongoDbPojo);
            insertLogToMongoDb.insertLog(logForMongoDbPojo);
        }
        log.error("path:{},errorMsg:{}", req.getContextPath() + req.getServletPath() + "?" + req.getQueryString(), e.getMessage());
        return Resp.response(RespEnum.SYSTEM_ERROR.getCode(), RespEnum.SYSTEM_ERROR.getMsg() + e.getMessage(), String.valueOf(req.getAttribute("traceId")));
    }


    /**
     * 自定义异常拦截 （AppException）
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(AppException.class)
    public Resp appExceptionHandler(HttpServletRequest req, AppException e) {
        // 写入日志到mongoDb
        if (airCoreProperty.getSetLogToMongoDb()) {
            String url = String.valueOf(req.getRequestURL());
            if (!StringUtils.isEmpty(req.getQueryString())) {
                url = url + "?" + req.getQueryString();
            }
            LogForMongoDbPojo logForMongoDbPojo = new LogForMongoDbPojo();
            logForMongoDbPojo.setErrMsg(e.getMsg());
            logForMongoDbPojo.setCreateTime(LocalDateTime.now());
            logForMongoDbPojo.setUrl(url);
            logForMongoDbPojo.setTraceId(String.valueOf(req.getAttribute("traceId")));
            logForMongoDbPojo.setIp(req.getRemoteAddr());
            logForMongoDbPojo.setMethod(req.getMethod());
            logForMongoDbPojo.setErrCode(e.getCode());
            parseHeaderAuthorization.setLoginInfo(logForMongoDbPojo);
            insertLogToMongoDb.insertLog(logForMongoDbPojo);
        }
        log.error("path:{},errorMsg:{}", req.getContextPath() + req.getServletPath() + "?" + req.getQueryString(), e.getMessage());
        return Resp.response(e.getCode(), e.getMsg(), String.valueOf(req.getAttribute("traceId")));
    }

}
